package com.lantosec.hmrp.modules.eval.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lantosec.hmrp.core.config.InitDataListener;
import com.lantosec.hmrp.core.kit.PageVO;
import com.lantosec.hmrp.core.shiro.TokenUtil;
import com.lantosec.hmrp.core.util.DateUtils;
import com.lantosec.hmrp.modules.eval.entity.*;
import com.lantosec.hmrp.modules.eval.mapper.EvalTaskMapper;
import com.lantosec.hmrp.modules.eval.service.*;
import com.lantosec.hmrp.modules.eval.vo.*;
import com.lantosec.hmrp.modules.system.entity.SysUser;
import com.lantosec.hmrp.modules.system.service.ISysUserService;
import com.lantosec.hmrp.modules.uploads.entity.SysUploads;
import com.lantosec.hmrp.modules.uploads.service.ISysUploadsService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 考评任务 服务实现类
 * </p>
 *
 * @author AutoCode
 * @since 2020-03-30
 */
@Service
@Primary
@Log4j2
@Transactional(rollbackFor = Exception.class)
@SuppressWarnings("all")
public class EvalTaskServiceImpl extends ServiceImpl<EvalTaskMapper, EvalTask> implements IEvalTaskService {

    @Autowired
    private IEvalPlanService iEvalPlanService;

    @Autowired
    private IEvalTaskEventService iEvalTaskEventService;

    @Autowired
    private IEvalEventExtradutyService iEvalEventExtradutyService;

    @Autowired
    private ISysUploadsService iSysUploadsService;

    @Autowired
    private IEvalDetailedService iEvalDetailedService;

    @Autowired
    private IEvalTaskItemService iEvalTaskItemService;

    @Autowired
    private IEvalDetailedItemService iEvalDetailedItemService;

    @Autowired
    private ISysUserService iSysUserService;

    @Override
    public List<EvalPlanVO> getNotFinishedTask(
            PageVO<EvalPlanVO> page, String startDate, String endDate,
            String evalPlanName, Integer evalPlanCycle, Integer evalPlanType,
            Integer evalMode, Integer state, Integer permissionsType,
            String userId, String deptId) {
        if (null == permissionsType) {
            permissionsType = 1;
        }
        List<EvalPlanVO> evalPlanVOList = null;
        //查询考评计划基本信息
        evalPlanVOList = getEvalPlanList(page, startDate, endDate, evalPlanName,
                evalPlanCycle, evalPlanType, evalMode, state, permissionsType, userId, deptId);
        evalPlanVOList.forEach(parm -> {
            Integer evalPlanId = parm.getEvalPlanId();
            Integer targetMode = parm.getTargetMode();
            //查询考评计划执行者
            List<EvalPlanExecutor> evalPlanExecutorList = iEvalPlanService.getEvalPlanExecutor(evalPlanId);
            //查询考评计划执行对象
            List<EvalPlanTarget> evalPlanTargetList = iEvalPlanService.getEvalPlanTarget(evalPlanId, targetMode);
            parm.setEvalPlanExecutorList(evalPlanExecutorList);
            parm.setEvalPlanTargetList(evalPlanTargetList);
            //计算考评任务进度
            Integer performNum = parm.getPerformNum();
            Integer targetNum = parm.getTargetNum();
            DecimalFormat df = new DecimalFormat("0");
            Integer progress = Integer.parseInt(df.format((float) performNum / targetNum * 100));
            parm.setProgress(progress);
        });
        page.setRecords(evalPlanVOList);
        return evalPlanVOList;
    }


    /**
     * @date: 2020-06-30 19:14
     * @instructions: 根据权限获取需要展示的考评列表
     * @param:
     * @return:
     */
    private List<EvalPlanVO> getEvalPlanList(PageVO<EvalPlanVO> page, String startDate, String endDate,
                                             String evalPlanName, Integer evalPlanCycle, Integer evalPlanType, Integer evalMode,
                                             Integer state, Integer permissionsType, String userId, String deptId) {
        List<EvalPlanVO> evalPlanVOList = new ArrayList<>();
        if(permissionsType == 1){
            evalPlanVOList = baseMapper.getNotFinishedTask(page, startDate, endDate,
                    evalPlanName, evalPlanCycle, evalPlanType, evalMode, state, permissionsType, userId);
        }
        if (permissionsType == 2) {
            evalPlanVOList = baseMapper.getNotFinishedTask(page, startDate, endDate,
                    evalPlanName, evalPlanCycle, evalPlanType, evalMode, state, permissionsType, deptId);
        }
        if (permissionsType == 3) {
            evalPlanVOList = baseMapper.getNotFinishedTask(page, startDate, endDate,
                    evalPlanName, evalPlanCycle, evalPlanType, evalMode, state, permissionsType, null);
        }
        return evalPlanVOList;
    }

    @Override
    public List<EvalPlanVO> getFinishedTask(PageVO<EvalPlanVO> page, String startDate, String endDate,
                                            String executorUser, Integer evalPlanCycle, Integer evalPlanType,
                                            Integer evalMode, Integer permissionsType, String userId, String deptId) {
        List<EvalPlanVO> evalPlanVOList = getFinishTask(page, startDate, endDate, executorUser,
                evalPlanCycle, evalPlanType, evalMode, permissionsType, userId, deptId);
        evalPlanVOList.forEach(parm -> {
            Integer evalPlanId = parm.getEvalPlanId();
            Integer targetMode = parm.getTargetMode();
            //查询考评计划执行者
            List<EvalPlanExecutor> evalPlanExecutorList = iEvalPlanService.getEvalPlanExecutor(evalPlanId);
            //查询考评计划执行对象
            List<EvalPlanTarget> evalPlanTargetList = iEvalPlanService.getEvalPlanTarget(evalPlanId, targetMode);
            parm.setEvalPlanExecutorList(evalPlanExecutorList);
            parm.setEvalPlanTargetList(evalPlanTargetList);
        });
        page.setRecords(evalPlanVOList);
        return evalPlanVOList;
    }


    /**
     * @date: 2020-06-30 20:15
     * @instructions: 根据权限展示已完成考评任务，
     * @param: permissionsType 1个人2科室3全院
     * @return:
     */
    private List<EvalPlanVO> getFinishTask(PageVO<EvalPlanVO> page, String startDate, String endDate,
                                           String executorUser, Integer evalPlanCycle, Integer evalPlanType,
                                           Integer evalMode, Integer permissionsType, String userId, String deptId) {
        List<EvalPlanVO> finishedTask = new ArrayList<>();
        if (permissionsType == null) {
            permissionsType = 1;
            finishedTask = baseMapper.getFinishedTask(page, startDate, endDate,
                    executorUser, evalPlanCycle, evalPlanType, evalMode, permissionsType, userId);

        }
        if (permissionsType == 2) {
            finishedTask = baseMapper.getFinishedTask(page, startDate, endDate,
                    executorUser, evalPlanCycle, evalPlanType, evalMode, permissionsType, deptId);
        }
        if (permissionsType == 3) {
            finishedTask = baseMapper.getFinishedTask(page, startDate, endDate,
                    executorUser, evalPlanCycle, evalPlanType, evalMode, permissionsType, null);
        }
        return finishedTask;
    }

    @Override
    public List<EvalTypeVO> get(Integer evalTaskId, Integer planTargetId) {
        //新增考评明细表和考评明细的项目表
        Integer evalDetailedId = insertEvalDetailed(evalTaskId, planTargetId);
        //查询考评任务所有信息
        List<EvalTypeVO> evalTypeVOS = getEvalTypeVOS(evalTaskId, evalDetailedId);
        return evalTypeVOS;
    }

    @Override
    public List<EvalTypeVO> getParm(Integer evalTaskId, Integer evalDetailedId) {
        List<EvalTypeVO> evalTypeVOS = getEvalTypeVOS(evalTaskId, evalDetailedId);
        return evalTypeVOS;
    }

    @Override
    public List<EvalPlanTarget> getFinishedTaskParm(Integer evalPlanId) {
        //查询考评计划中的考评对象形式是科室、岗位、人员
        EvalPlan evalPlan = iEvalPlanService.getById(evalPlanId);
        Integer targetMode = evalPlan.getTargetMode();
        //查询出考评已完成的考评对象
        List<EvalPlanTarget> evalPlanTargetList = baseMapper.getEvalPlanTarget(evalPlanId, targetMode);
        if (null != evalPlanTargetList && evalPlanTargetList.size() > 0) {
            evalPlanTargetList.forEach(parm -> {
                //查询出考评对象的考评项
                Integer planTargetId = parm.getPlanTargetId();
                //通过考评对象id查询考评对象明细列表，获得最后一次执行的数据
                List<EvalDetailed> evalDetailedList = iEvalDetailedService.list(new QueryWrapper<EvalDetailed>().eq(EvalDetailed.ColName.plan_target_id.toString(), planTargetId)
                        .eq(EvalDetailed.ColName.task_state.toString(), 2)
                        .orderByDesc(EvalDetailed.ColName.curr_exec_num.toString()));
                EvalDetailed evalDetailed = evalDetailedList.get(0);
                //查询出考评对象的考评项目
                List<EvalDetailedItemVO> evalDetailedItemVOList = baseMapper.getEvalItemByEvalDetailedId(evalDetailed.getEvalDetailedId());
                parm.setEvalDetailedItemVOList(evalDetailedItemVOList);
            });
        }
        return evalPlanTargetList;
    }

    @Override
    public void updateEvalTask(Integer evalDetailedId, Integer state) {
        //查询考评项目中项目分值/项目得分/项目金额的总和
        EvalDetailedItem evalDetailedItem = baseMapper.querySum(evalDetailedId);
        BigDecimal rewardStandard = evalDetailedItem.getRewardStandard();
        BigDecimal itemScore = evalDetailedItem.getItemScore();
        BigDecimal itemMoney = evalDetailedItem.getItemMoney();
        EvalDetailed evalDetailed = new EvalDetailed();
        evalDetailed.setPlanTotalScore(rewardStandard);
        evalDetailed.setPlanScore(itemScore);
        evalDetailed.setPlanMoney(itemMoney);
        evalDetailed.setEvalDetailedId(evalDetailedId);
        //如果是保存，则只更新状态和分值或者金额
        if (state == 1) {
            //更新任务状态
            evalDetailed.setTaskState(1);
            iEvalDetailedService.updateById(evalDetailed);
        } else {
            //如果是提交，则还需要更新对象执行完次数
            //更新任务状态
            evalDetailed.setTaskState(2);
            evalDetailed.setSubmitTime(DateUtils.nowDate());
            iEvalDetailedService.updateById(evalDetailed);
            evalDetailed = iEvalDetailedService.getById(evalDetailedId);
            //查询出考评对象周期内执行次数最大次数，更新考评任务执行完次数
            Integer evalTaskId = evalDetailed.getEvalTaskId();
            Integer performNum = baseMapper.queryPerformNum(evalTaskId);
            EvalTask evalTask = new EvalTask();
            evalTask.setEvalTaskId(evalTaskId);
            evalTask.setPerformNum(performNum);
            this.updateById(evalTask);
        }

    }

    @Override
    public List<EvalPlanTarget> startEval(Integer evalPlanId) {
        EvalPlan evalPlan = iEvalPlanService.getById(evalPlanId);
        //查询出考评计划中考评对象形式
        Integer targetMode = evalPlan.getTargetMode();
        //查询考评计划中的考评对象数
        List<EvalPlanTarget> evalPlanTargetList = baseMapper.getEvalPlanTarget(evalPlanId, targetMode);
        if (null != evalPlanTargetList && evalPlanTargetList.size() > 0) {
            evalPlanTargetList.forEach(parm -> {
                //如果被考评对象是部门
                if (targetMode == 1) {
                    parm.setTargetId(parm.getDeptId());
                    parm.setName(parm.getDeptName());
                }
                //如果被考评对象是岗位,考评对象是岗位下的所有人员
                if (targetMode == 2) {
                    String deptId = parm.getDeptId();
                    String positionId = parm.getPositionId();
                    //查询岗位下的所有人员
                    List<SysUser> sysUserList = iSysUserService.queryUser(deptId, positionId);
                    if (null != sysUserList && sysUserList.size() > 0) {
                        sysUserList.forEach(param -> {
                            parm.setTargetId(parm.getDeptId() + "-" + parm.getPositionId() + "-" + param.getUserId());
                            parm.setName(parm.getDeptName() + "-" + parm.getPositionName() + "-" + param.getName());
                        });
                    }
                }
                //如果考评对象是人员
                if (targetMode == 3) {
                    parm.setTargetId(parm.getDeptId() + "-" + parm.getUserId());
                    parm.setName(parm.getDeptName() + "-" + parm.getName());
                }
                //查询对象被考评的次数列表
                List<EvalDetailedVO> evalDetailedList = baseMapper.getEvalDetailed(parm.getPlanTargetId(), parm.getTargetMode());
                evalDetailedList.forEach(parm1 -> {
                    //返回考评对象的考评图片路径
                    String evalStartPhoto = parm1.getEvalStartPhoto();
                    if (StringUtils.isNotEmpty(evalStartPhoto)) {
                        SysUploads sysUploads = iSysUploadsService.getById(evalStartPhoto);
                        String savePath = sysUploads.getSavePath();
                        String fileName = sysUploads.getFileName();
                        parm1.setSavePath(InitDataListener.uploadsUrl + savePath + fileName);
                    }
                    //查询考评对象的事件数
                    Integer evalDetailedId = parm1.getEvalDetailedId();
                    List<EvalTaskEvent> evalTaskEventList = iEvalTaskEventService.list(new QueryWrapper<EvalTaskEvent>().eq(EvalTaskEvent.ColName.eval_detailed_id.toString(), evalDetailedId));
                    parm1.setEvalTaskEventList(evalTaskEventList);
                });
                parm.setEvalDetailedList(evalDetailedList);
            });
        }
        return evalPlanTargetList;
    }


    /**
     * 查询考评任务所有信息
     *
     * @param evalTaskId
     * @return
     */
    private List<EvalTypeVO> getEvalTypeVOS(Integer evalTaskId, Integer evalDetailedId) {
        //查询考评任务下的考评项目分类
        List<EvalTypeVO> evalTypeVOS = baseMapper.getEvalType(evalTaskId);
        evalTypeVOS.forEach(parm -> {
            String evalTypeId = parm.getEvalTypeId();
            //查询考评任务下的项目类型下的所有项目
            List<EvalDetailedItemVO> evalDetailedItemVOList = baseMapper.getEvalDetailedItem(evalTypeId, evalDetailedId);
            evalDetailedItemVOList.forEach(parm1 -> {
                Integer evalDetailedItemId = parm1.getEvalDetailedItemId();
                //查询事件列表
                List<EvalTaskEvent> evalTaskEventList = iEvalTaskEventService.list(new QueryWrapper<EvalTaskEvent>()
                        .eq(EvalTaskEvent.ColName.eval_detailed_item_id.toString(), evalDetailedItemId).orderByDesc(EvalTaskEvent.ColName.create_time.toString()));
                List<EvalTaskEventVO> evalTaskEventVOList = new ArrayList<>();
                //添加事件下的追究责任列表
                evalTaskEventList.forEach(parm3 -> {
                    Integer evalTaskEventId = parm3.getEvalTaskEventId();
                    List<EvalEventExtraduty> evalEventExtradutyList = iEvalEventExtradutyService.list(new QueryWrapper<EvalEventExtraduty>()
                            .eq(EvalEventExtraduty.ColName.eval_task_event_id.toString(), evalTaskEventId));
                    EvalTaskEventVO evalTaskEventVO = parm3.convertToVO();
                    //添加事件的图片路径
                    if (StringUtils.isNotEmpty(evalTaskEventVO.getEvidencePhotoList())) {
                        String[] photoId = evalTaskEventVO.getEvidencePhotoList().split(",");
                        List list = new ArrayList();
                        for (String s : photoId) {
                            try {
                                SysUploads sysUploads = iSysUploadsService.getById(s);
                                String savePath = sysUploads.getSavePath();
                                String fileName = sysUploads.getFileName();
                                list.add(InitDataListener.uploadsUrl + savePath + fileName);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        evalTaskEventVO.setSavePath(list);
                    }
                    evalTaskEventVO.setEvalEventExtradutyList(evalEventExtradutyList);
                    evalTaskEventVOList.add(evalTaskEventVO);
                });
                parm1.setEvalTaskEventVOList(evalTaskEventVOList);
            });
            parm.setEvalDetailedItemVOList(evalDetailedItemVOList);
            //查询出考评任务内的所有事项的加减总分
            BigDecimal rewardValueSum = baseMapper.getRewardValueSum(evalDetailedId);
            parm.setRewardValueSum(rewardValueSum);
            parm.setEvalDetailedId(evalDetailedId);
        });
        return evalTypeVOS;
    }

    /**
     * 开始考评新增考评明细表和考评明细的项目表
     *
     * @param evalTaskId
     * @param planTargetId
     */
    private Integer insertEvalDetailed(Integer evalTaskId, Integer planTargetId) {
        //先查询考评名表中的考评对象是否已存在，存在即更新执行次数
        List<EvalDetailed> evalDetailedList = iEvalDetailedService.list(new QueryWrapper<EvalDetailed>().eq(EvalDetailed.ColName.eval_task_id.toString(), evalTaskId)
                .eq(EvalDetailed.ColName.plan_target_id.toString(), planTargetId)
                .orderByDesc(EvalDetailed.ColName.curr_exec_num.toString()));
        //如果当前考评对象不存在，即存新增考评对象
        if (null == evalDetailedList || evalDetailedList.size() == 0) {
            EvalDetailed evalDetailed = new EvalDetailed();
            evalDetailed.setEvalTaskId(evalTaskId);
            evalDetailed.setPlanTargetId(planTargetId);
            //获取当前用户id和名称
            String userId = TokenUtil.getUserId();
            String userName = TokenUtil.getName();
            evalDetailed.setExecutorUserId(userId);
            evalDetailed.setExecutorUser(userName);
            evalDetailed.setExecutorTime(DateUtils.nowDate());
            evalDetailed.setTaskState(0);
            evalDetailed.setCurrExecNum(1);
            iEvalDetailedService.save(evalDetailed);
            //新增考评明细的项目表
            //先查询当前任务id的考评项目
            List<EvalTaskItem> evalTaskItemList = iEvalTaskItemService.list(new QueryWrapper<EvalTaskItem>().eq(EvalTaskItem.ColName.eval_task_id.toString(), evalTaskId));
            evalTaskItemList.forEach(parm -> {
                EvalDetailedItem evalDetailedItem = new EvalDetailedItem();
                evalDetailedItem.setEvalDetailedId(evalDetailed.getEvalDetailedId());
                evalDetailedItem.setEvalTaskId(evalTaskId);
                evalDetailedItem.setEvalItemId(parm.getEvalItemId());
                evalDetailedItem.setRewardOrientation(parm.getRewardOrientation());
                evalDetailedItem.setRewardType(parm.getRewardType());
                evalDetailedItem.setRewardStandard(parm.getRewardStandard());
                //TODO 巡查 项目得分是否一开始就有基础分
                if (null != parm.getRewardUpLimit()) {
                    evalDetailedItem.setRewardUpLimit(parm.getRewardUpLimit());
                }
                if (null != parm.getRewardLowLimit()) {
                    evalDetailedItem.setRewardLowLimit(parm.getRewardLowLimit());
                }
                evalDetailedItem.setExtraItem(0);
                iEvalDetailedItemService.save(evalDetailedItem);
            });
            return evalDetailed.getEvalDetailedId();
        } else {
            EvalDetailed evalDetailed1 = evalDetailedList.get(0);
            EvalDetailed evalDetailed = new EvalDetailed();
            Integer evalDetailedId = evalDetailed1.getEvalDetailedId();
            evalDetailed.setEvalTaskId(evalTaskId);
            evalDetailed.setPlanTargetId(planTargetId);
            //获取当前用户id和名称
            String userId = TokenUtil.getUserId();
            String userName = TokenUtil.getName();
            evalDetailed.setExecutorUserId(userId);
            evalDetailed.setExecutorUser(userName);
            evalDetailed.setExecutorTime(DateUtils.nowDate());
            //重新考评清空提交时间、总分、得分、金额
            evalDetailed.setSubmitTime(null);
            evalDetailed.setPlanTotalScore(null);
            evalDetailed.setPlanScore(null);
            evalDetailed.setPlanMoney(null);
            evalDetailed.setTaskState(0);
            Integer currExecNum = evalDetailed1.getCurrExecNum();
            evalDetailed.setCurrExecNum(currExecNum + 1);
            iEvalDetailedService.save(evalDetailed);
            //新增考评明细的项目表
            //先查询当前考评对象的上一次考评的考评项目然后复制到当前考评
            List<EvalDetailedItem> evalDetailedItemList = iEvalDetailedItemService.list(new QueryWrapper<EvalDetailedItem>().eq(EvalDetailedItem.ColName.eval_detailed_id.toString(), evalDetailedId));
            evalDetailedItemList.forEach(parm -> {
                EvalDetailedItem evalDetailedItem = new EvalDetailedItem();
                evalDetailedItem.setEvalDetailedId(evalDetailed.getEvalDetailedId());
                evalDetailedItem.setEvalTaskId(evalTaskId);
                evalDetailedItem.setEvalItemId(parm.getEvalItemId());
                evalDetailedItem.setRewardOrientation(parm.getRewardOrientation());
                evalDetailedItem.setRewardType(parm.getRewardType());
                evalDetailedItem.setRewardStandard(parm.getRewardStandard());
                if (null != parm.getRewardUpLimit()) {
                    evalDetailedItem.setRewardUpLimit(parm.getRewardUpLimit());
                }
                if (null != parm.getRewardLowLimit()) {
                    evalDetailedItem.setRewardLowLimit(parm.getRewardLowLimit());
                }
                evalDetailedItem.setExtraItem(0);
                iEvalDetailedItemService.save(evalDetailedItem);
            });
            return evalDetailed.getEvalDetailedId();
        }

    }
}
